package com.yunao.service.impl;

import com.yunao.commons.Exception.YunaoException;
import com.yunao.commons.enums.ArticleType;
import com.yunao.commons.enums.ResultEnum;
import com.yunao.commons.serachcore.core.bean.Article;
import com.yunao.commons.serachcore.core.bean.Articles;
import com.yunao.dao.ArticleRepository;
import com.yunao.entity.ArticleItem;
import com.yunao.entity.User;
import com.yunao.service.ArticleService;
import com.yunao.service.convert.Article2Iten;
import com.yunao.service.report.Convert;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.*;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleRepository articleRepository;

    @Autowired
    private IsearchServiceImpl isearchService;


    @Override
    public Articles seachByids(String ids) {
        Map map = new HashMap<String,String>();
        map.put("id",ids);
        Articles articles = isearchService.query(map);
        return articles;
    }

    @Override
    public ArticleItem findOne(Integer articleId) {
        return articleRepository.findById(articleId).get();
    }

    @Override
    public void deleteById(Integer articleId) {
        articleRepository.deleteById(articleId);
    }

    @Override
    public void deleteByIds(String articleIds) {
        if (StringUtils.isEmpty(articleIds)){
            throw new YunaoException(ResultEnum.ARTICLE_EMPTY);
        }
        int[] ids = Convert.str2int(articleIds.split(","));
        List<Integer> list = Arrays.stream(ids).boxed().collect(Collectors.toList());
        List<ArticleItem> idlist = list.stream()
                .map(e->articleRepository.findById(e).get())
                .collect(Collectors.toList());
        articleRepository.deleteInBatch(idlist);
    }

    @Override
    public List<ArticleItem> findAllById(String ids) {
        int[] idarrs = Convert.str2int(ids.split(","));
        List<Integer> list = Arrays.stream(idarrs).boxed().collect(Collectors.toList());
        return articleRepository.findAllById(list);
    }

    @Override
    public List<ArticleItem> findByUserAndType(Integer userId, Integer type) {
        return articleRepository.findAllByArticleUserIdAndArticleType(userId,type);
    }

    @Override
    public Page<ArticleItem> findByQuery(Integer userId, Integer type,Date date,String word, Pageable pageable) {
        return articleRepository.findAll(new Specification<ArticleItem>() {
            @Override
            public Predicate toPredicate(Root<ArticleItem> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<Integer> useridpath = root.get("articleUserId");
                Path<Integer> typepath = root.get("articleType");
                Path<Date> datepath = root.get("articlePubdate");
                Path<String> txpath = root.get("articleText");
                List<Predicate> list = new ArrayList<Predicate>();
                if (userId != null && !"".equals(userId)) {
                    list.add(cb.equal(useridpath, userId));
                }
                if (type != null && !"".equals(type)) {
                    list.add(cb.equal(typepath, type));
                }
                if (date != null && !"".equals(date)){
                    list.add(cb.greaterThan(datepath,date));
                }
                if (word != null && !"".equals(word)){
                    list.add(cb.like(txpath,"%"+word+"%"));
                }
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        },pageable);
    }

    @Override
    public List<ArticleItem> findByWord(String word) {
        return articleRepository.findAllByArticleTextLike(word);
    }

    @Override
    public Page<ArticleItem> findAlarms(Integer userId,Integer type,String word,Date numday,Date day,Integer subjectId,Pageable pageable) {
        return articleRepository.findAll(new Specification<ArticleItem>() {
            @Override
            public Predicate toPredicate(Root<ArticleItem> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<Integer> useridpath = root.get("articleUserId");
                Path<Integer> typepath = root.get("articleType");
                Path<Date> datepath = root.get("articleLoadTime");
                Path<String> subjectpath = root.get("articleSubjectId");
                Path<String> textpath = root.get("articleText");
                List<Predicate> list = new ArrayList<Predicate>();
                if (userId != null && !"".equals(userId)) {
                    list.add(cb.equal(useridpath, userId));
                }
                if (type != null && !"".equals(type)) {
                    list.add(cb.equal(typepath, type));
                }
                if (word != null && !"".equals(word)) {
                    list.add(cb.like(textpath,word));
                }
                if (numday != null && !"".equals(numday)) {
                    list.add(cb.equal(datepath, numday));
                }else{
                    if (day != null && !"".equals(day)){
                        list.add(cb.greaterThan(datepath,day));
                    }
                }
                if (subjectId != null && !"".equals(subjectId)){
                    list.add(cb.equal(subjectpath,subjectId));
                }
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        },pageable);
    }

    @Override
    public Page<ArticleItem> getArticleItems(Integer userid, Integer type, Pageable pageable) {
        return articleRepository.findAll(new Specification<ArticleItem>() {
            @Override
            public Predicate toPredicate(Root<ArticleItem> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Path<String> useridpath = root.get("articleUserId");
                Path<String> typepath = root.get("articleType");
                List<Predicate> list = new ArrayList<Predicate>();
                if (userid != null && !"".equals(userid)) {
//                    list.add(cb.like(useridpath,"%"+userid+"%"));
                    list.add(cb.equal(useridpath, userid));
                }
                if (type != null && !"".equals(type)) {
                    list.add(cb.equal(typepath, type));
                }
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        },pageable);
        }


    @Override
    public void save(Articles articles, User userOutput) {
        List articleList = new ArrayList();

        List<ArticleItem> list = articleRepository.findAllByArticleUserIdAndArticleType(userOutput.getUserId(),ArticleType.FAVORITE.getCode());
        Set<String> setids = list.stream()
                .map(e->e.getSearchId())
                .collect(Collectors.toSet());
        if (articles.getData().size()==1){
            if (!setids.add(articles.getData().get(0).getId()+"")){
                throw new YunaoException(ResultEnum.ARTICLE_EXIET);
            }
       }
        for (Article article:articles.getData()) {
            if (!setids.add(article.getId()+"")){
                continue;
            }
            ArticleItem articleItem = Article2Iten.convert(article);
            articleItem.setArticleUserId(userOutput.getUserId());
            articleList.add(articleItem);
        }
        System.out.println(userOutput.getUsername()+"添加收藏"+articleList.size()+"条");
        articleRepository.saveAll(articleList);
    }

    @Override
    public List<ArticleItem> findBySubject(Integer subjectId) {
        return articleRepository.findAllByArticleSubjectId(subjectId);
    }
}
